﻿﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using WorldMapBase;
using WorldMapBase.Display;
using WorldMapBase.Tile;
using WorldMapBase.Tile.Pool;
using WorldMapNew;
using XLua;
 using Yoozoo.Core.Extensions.CSharp;
 using Yoozoo.Framework.Managers;
using Yoozoo.UI.Tools;
using static WorldMapBase.WorldMapConfigData;

public class MapPointAdornSystem : MonoBehaviour
{
    public enum E_AdornType { 
        E_Level_1 = 1,
        E_Level_2 = 2,
        E_Level_n = 3,
        E_Road = 4,// 衔接道路
        E_Null = 5,// 空置装饰物
    }

    Dictionary<int, Dictionary<int, bool>> mapPointState = new Dictionary<int, Dictionary<int, bool>>(); // <tileIdx,<cfgIdx,state>> 地图出生点状态 -只有数据更新回调中才是最新的
    Dictionary<int, Dictionary<int, bool>> mapPointState2 = new Dictionary<int, Dictionary<int, bool>>(); // <tileIdx,<pointIdx,state>> 地图出生点状态 - 这里是世界坐标的idx
    Dictionary<int, Dictionary<int, bool>> mapPointDisAdorn = new Dictionary<int, Dictionary<int, bool>>(); // <tileIdx,<cfgIdx,disAdorn>> 地图主城皮肤装饰物失效状态 -只有点数据更新中才是正确的
    Dictionary<int, Dictionary<int, CommandTileElement>> mapAdornElements = new Dictionary<int, Dictionary<int, CommandTileElement>>(4);// <tileIdx,<adornUid,CommandTileElement>>
    Dictionary<int, Dictionary<int, CommandTileElement>> mapTiles = new Dictionary<int, Dictionary<int, CommandTileElement>>(); // <tileIdx,<cfgIdx,CommandTileElement>>

    const int m_tile_resId_1 = 7; // 全包围
    const int m_tile_resId_2 = 8;
    const int m_tile_resId_3 = 9;
    const int m_tile_resId_4 = 10;
    const int m_tile_resId_5 = 11;
    const int m_tile_resId_6 = 12;

    public bool isEnable = true;
    int _chunckSize = 30;
    int _chunckHalfSize = 15;

    Dictionary<int, bool> mapShowTileIdxs = new Dictionary<int, bool>();// 当前客户端显示的地表idx 集合
    Dictionary<int, Dictionary<int, int>> mapPointPosIdx = new Dictionary<int, Dictionary<int, int>>(); // <tileIdx,<cfgIdx,posIdx>> 

    private LuaFunction luaSendFunc;

    private IDisplayCommandInterface m_DisplayCommandInterface;

    public void Init(IDisplayCommandInterface displayCommandInterface)
    {
        _chunckSize = WorldEntry.m_iTileSize;
        _chunckHalfSize = _chunckSize / 2;
        m_DisplayCommandInterface = displayCommandInterface;
        luaSendFunc = LuaManager.mainState.GetFunction("L_SandBoxManager.sendMapAreaPointRequest");
    }

    public void DisPose(bool isLod = true)
    {
        isEnable = false;
        mapPointState.Clear();
        mapPointState2.Clear();
        foreach (var adorns in mapAdornElements.Values)
        {
            if (adorns != null)
            {
                foreach (var adorn in adorns.Values)
                {
                    if (adorn != null)
                    {
                        ClassPoolManager.RecoverCommandTileEle(adorn);
                    }
                }
            }
        }
        mapAdornElements.Clear();
        foreach (var tiles in mapTiles.Values)
        {
            if (tiles != null)
            {
                foreach (var tile in tiles.Values)
                {
                    if (tile != null)
                    {
                        ClassPoolManager.RecoverCommandTileEle(tile);
                    }
                }
            }
        }
        mapTiles.Clear();
        mapShowTileIdxs.Clear();
        if (!isLod)
        {
            mapPointPosIdx.Clear();
            luaSendFunc = null;
        }
    }

    public void OnSystemEnable()
    {
        isEnable = true;
    }

    // ============================================================ 更新 ============================================================ 

    /// <summary>
    /// 更新点装饰物的表现
    /// </summary>
    /// <param name="tileIdx"></param>
    /// <param name="posIdx"></param>
    /// <param name="state"></param>
    /// <param name="point_x"></param>
    /// <param name="point_y"></param>
    /// <param name="iDisAdorn">是否禁用该点的装饰物功能 -1不禁用 0不设置 1禁用 </param>
    public void UpdatePointState(int tileIdx, int posIdx,bool state, float point_x, float point_y,int iDisAdorn)
    {
        //StopwatchHelper.Instance.StartWatch("[UpdatePointState]", true);
        bool tileNoShowing = (!mapShowTileIdxs.ContainsKey(tileIdx) || !mapShowTileIdxs[tileIdx]);
        bool bEnableShow = (!isEnable && state);
        int chunckId = WorldMapConfigData.GetChunckId(tileIdx, out int rotation);
        float idx_x = point_x % WorldEntry.m_iTileSize;
        float idx_y = point_y % WorldEntry.m_iTileSize;
        Vector3 cfg_v3 = WorldMapConfigData.GetPosByAngle2(idx_x - _chunckHalfSize, 0, idx_y - _chunckHalfSize, rotation);
        int cfgIdx = GetLocalIdx((int)(cfg_v3.x + _chunckHalfSize), (int)(cfg_v3.z + _chunckHalfSize)); // 配置中的localIdx
        bool oldDisAdorn = GetPointDisAdorn(tileIdx, cfgIdx);
        if (iDisAdorn != 0) // 这里要优先保存一下禁用装饰物功能数据
        {
            SetPointDisAdorn(tileIdx, cfgIdx, iDisAdorn > 0);
        }
        if (tileNoShowing || bEnableShow) return;
        bool oldState = GetPointState(tileIdx, cfgIdx);
        if (oldState != state || (oldDisAdorn != (iDisAdorn > 0) && iDisAdorn != 0))
        {
            Vector3 tileOffset = WorldMapConfigData.GetTileOffset(tileIdx);
            // 记录状态
            SetPointState(tileIdx, cfgIdx, state);
            SetPointState2(tileIdx, posIdx, state);
            
            SetPointPosIdx(tileIdx, cfgIdx, posIdx);
            // 更新多级装饰物
            UpdateAdornLevel(chunckId, tileIdx, cfgIdx, E_AdornType.E_Level_n, state, tileOffset, rotation);
            // 更新二级装饰物
            UpdateAdornLevel(chunckId, tileIdx, cfgIdx, E_AdornType.E_Level_2, state, tileOffset, rotation);
            // 更新一级装饰物
            UpdateAdornLevel(chunckId, tileIdx, cfgIdx, E_AdornType.E_Level_1, state, tileOffset, rotation);
            // 更新空置装饰物
            // UpdateAdornLevel_null(chunckId, tileIdx, cfgIdx, state, tileOffset, rotation);
            // 更新衔接车道
            UpdateAdornRoad(chunckId, tileIdx, cfgIdx, state, tileOffset, rotation, point_x, point_y);
            // 更新地表
            UpdatePointTile(chunckId, tileIdx, cfgIdx, rotation);
        }
        //StopwatchHelper.Instance.EndWatch("[UpdatePointState]", true);
    }

    // 更新多级装饰物
    public void UpdateAdornLevel(int chunckId,int tileIdx,int cfgIdx, E_AdornType type, bool state,Vector3 tileOffset,int rotation)
    {
        // 1、获取装饰物
        List<TilePointAdornData> adornDatas = GetAdornDatas(chunckId, cfgIdx, (int)type);
        if (adornDatas == null) return;
        for (int x = 0; x < adornDatas.Count; x++)
        {
            TilePointAdornData adornData = adornDatas[x];
            if (state)
            {
                // 2、判断该多级装饰物显示条件满足
                bool bShow = true;
                for (int i = 0; i < adornData.pointIdxs.Count; i++)
                {
                    int pointCfgIdx = adornData.pointIdxs[i];
                    bool bPointShow = GetPointState(tileIdx, pointCfgIdx);
                    bool disAdorn = GetPointDisAdorn(tileIdx, pointCfgIdx);
                    if (!bPointShow || disAdorn)
                    {
                        bShow = false;
                        break;
                    }
                }

                if (bShow)
                {
                    // 4、新增多级装饰物
                    CommandTileElement obj = GetAdornElement(tileIdx, adornData.uid);
                    if (obj == null)
                    {
                        Vector3 localOffset = WorldMapConfigData.GetPosByAngle(adornData.position.x, 0, adornData.position.z, rotation);
                        bool bHide = GetHightPointAdornShow(tileIdx, adornData);
                        CommandTileElement adornElement = CommandTileElement.Create(WorldEntry.MAP_POINT_ADORN_LAYER_ID, adornData, 
                            tileOffset + localOffset, bHide, rotation, m_DisplayCommandInterface);

                        //obj.GetRefTrans.gameObject.name = string.Format("{0}_{1}_{2}", tileIdx, adornData.uid, adornData.type);
                        SetAdornTileElement(tileIdx, adornData.uid, adornElement);
                    }
                    // 5、隐藏所有下级装饰物
                    UpdateLowPointAdornShow(tileIdx, adornData, false);
                }
                else
                {
                    // 检查该多级装饰物 是否显示
                    CommandTileElement obj = GetAdornElement(tileIdx, adornData.uid);
                    if (obj != null)
                    {
                        RemoveAdorn(tileIdx, adornData.uid);
                        // 更新所有出生点装饰物显示 
                        UpdateLowPointAdornShow(tileIdx, adornData, true);
                    }
                }
            }
            else
            {
                // 检查该多级装饰物 是否显示
                CommandTileElement obj = GetAdornElement(tileIdx, adornData.uid);
                if (obj != null)
                {
                    RemoveAdorn(tileIdx, adornData.uid);
                    // 更新所有出生点装饰物显示 
                    UpdateLowPointAdornShow(tileIdx, adornData, true);
                }
            }
        }
    }

    // 更新空置装饰物
    public void UpdateAdornLevel_null(int chunckId, int tileIdx, int cfgIdx, bool state, Vector3 tileOffset, int rotation)
    {
        List<TilePointAdornData> adornDatas = GetAdornDatas(chunckId, cfgIdx, (int)E_AdornType.E_Null);
        if (adornDatas == null) return;
        for (int x = 0; x < adornDatas.Count; x++)
        {
            TilePointAdornData adornData = adornDatas[x];
            if (state)
            {
                // 检查空置装饰物 是否显示
                CommandTileElement obj = GetAdornElement(tileIdx, adornData.uid);
                if (obj != null)
                {
                    RemoveAdorn(tileIdx, adornData.uid);
                }
            }
            else
            {
                // 检查空置装饰物 是否显示
                CommandTileElement obj = GetAdornElement(tileIdx, adornData.uid);
                if (obj == null)
                {
                    Vector3 localOffset = WorldMapConfigData.GetPosByAngle(adornData.position.x, 0, adornData.position.z, rotation);
                    CommandTileElement adornElement = CommandTileElement.Create(WorldEntry.MAP_POINT_ADORN_LAYER_ID, adornData,
                        tileOffset + localOffset, false, rotation, m_DisplayCommandInterface);
                    SetAdornTileElement(tileIdx, adornData.uid, adornElement);
                }
            }
        }
    }

    // 更新衔接车道
    public void UpdateAdornRoad(int chunckId, int tileIdx, int cfgIdx, bool state, Vector3 tileOffset, int rotation, float point_x, float point_y)
    {
        List<TilePointAdornData> adornDatas = GetAdornDatas(chunckId, cfgIdx, (int)E_AdornType.E_Road);
        if (adornDatas == null) return;
        for (int x = 0; x < adornDatas.Count; x++)
        {
            TilePointAdornData adornData = adornDatas[x];
            if (state)
            {
                // 检查adornData所在街区点是否显示
                int allianceIdx = DynamicLayerMgr.worldEntry._alliancePointSystem.GetMapIdx(point_x, point_y);
                bool bAlliancePointShow = DynamicLayerMgr.worldEntry._alliancePointSystem.GetAlliancePointShow(allianceIdx);
                if (!bAlliancePointShow) return;
                CommandTileElement obj = GetAdornElement(tileIdx, adornData.uid);
                if (obj == null)
                {
                    Vector3 localOffset = WorldMapConfigData.GetPosByAngle(adornData.position.x, 0, adornData.position.z, rotation);
                    CommandTileElement adornElement = CommandTileElement.Create(WorldEntry.MAP_POINT_ADORN_LAYER_ID, adornData,
                    tileOffset + localOffset, false, rotation, m_DisplayCommandInterface);
                    SetAdornTileElement(tileIdx, adornData.uid, adornElement);
                }
            }
            else
            {
                CommandTileElement obj = GetAdornElement(tileIdx, adornData.uid);
                if (obj != null)
                {
                    RemoveAdorn(tileIdx, adornData.uid);
                }
            }
        }
    }

    Dictionary<int, bool> tempNeedUpdateTileCfgIdx = new Dictionary<int, bool>(); // 需要更新地表的cfgIdx缓存集合
    public void UpdatePointTile(int chunckId, int tileIdx, int cfgIdx, int rotation)
    {
        tempNeedUpdateTileCfgIdx.Clear();
        tempNeedUpdateTileCfgIdx[cfgIdx] = true;
        List<TilePointAdornData> adornDatas = GetAdornDatas(chunckId, cfgIdx, (int)E_AdornType.E_Level_2);
        if (adornDatas == null) return;
        for (int i = 0; i < adornDatas.Count; i++)
        {
            TilePointAdornData adornData = adornDatas[i];
            for (int ii = 0; ii < adornData.pointIdxs.Count; ii++)
            {
                int cfgIdx1 = adornData.pointIdxs[ii];
                if (cfgIdx1 != cfgIdx)
                {
                    tempNeedUpdateTileCfgIdx[cfgIdx1] = true;
                }
            }
        }
        UpdatePointTile2(chunckId, tileIdx, rotation,true); // 直接调用UpdatePointTile2更新所有需要更新的地表
        tempNeedUpdateTileCfgIdx.Clear();
    }

    // ============================================================ 删除 ============================================================ 

    public void RemoveAdorn(int tileIdx, int uid)
    {
        if (mapAdornElements.ContainsKey(tileIdx))
        {
            Dictionary<int, CommandTileElement> adorns = mapAdornElements[tileIdx];
            if (adorns.ContainsKey(uid))
            {
                CommandTileElement obj = adorns[uid];
                ClassPoolManager.RecoverCommandTileEle(obj);
                adorns.Remove(uid);
            }
        }
    }

    // ============================================================ 其他 ============================================================ 

    // 添加一个块的空置装饰物（删除统一走删除步骤）
    public void AddAdornNull(int tileIdx)
    {
        int chunckId = WorldMapConfigData.GetChunckId(tileIdx, out int rotation);
        List<TilePointAdornData> adornDatas = GetChunckAdornDatas(chunckId, (int)E_AdornType.E_Null);
        Vector3 tileOffset = WorldMapConfigData.GetTileOffset(tileIdx);
        for (int i = 0; i < adornDatas.Count; i++)
        {
            TilePointAdornData adornData = adornDatas[i];
            CommandTileElement obj = GetAdornElement(tileIdx, adornData.uid);
        
            bool bPointShow = GetPointState(tileIdx, adornData.pointIdxs[0]);
            if (obj == null && !bPointShow)
            {
                Vector3 localOffset = WorldMapConfigData.GetPosByAngle(adornData.position.x, 0, adornData.position.z, rotation);
                CommandTileElement adornElement = CommandTileElement.Create(WorldEntry.MAP_POINT_ADORN_LAYER_ID, adornData,
                            tileOffset + localOffset, false, rotation, m_DisplayCommandInterface);
                SetAdornTileElement(tileIdx, adornData.uid, adornElement);
            }
        }
    }

    // 更新一个块的衔接道路
    public void UpdateAdornRoad(int tileIdx,int allianceIdx, bool bShow)
    {
        int chunckId = WorldMapConfigData.GetChunckId(tileIdx, out int rotation);
        List<TilePointAdornData> adornDatas = GetChunckAdornDatas(chunckId, (int)E_AdornType.E_Road);
        if (adornDatas == null) return;
       
        Vector3 tileOffset = WorldMapConfigData.GetTileOffset(tileIdx);
        for (int i = 0; i < adornDatas.Count; i++)
        {
            TilePointAdornData adornData = adornDatas[i];
            CommandTileElement obj = GetAdornElement(tileIdx, adornData.uid);
            if (bShow)
            {
                bool bPointShow = GetPointState(tileIdx, adornData.pointIdxs[0]);
                if (obj == null && bPointShow)
                {
                    Vector3 worldPos = GetPosByAngle2(adornData.position.x, adornData.position.y, adornData.position.z, rotation);
                    worldPos += tileOffset;
                    int allianceIdx0 = DynamicLayerMgr.worldEntry._alliancePointSystem.GetMapIdx(worldPos.x, worldPos.y);
                    if (allianceIdx0 != allianceIdx) continue;
                   
                    Vector3 localOffset = WorldMapConfigData.GetPosByAngle(adornData.position.x, 0, adornData.position.z, rotation);
                    CommandTileElement adornElement = CommandTileElement.Create(WorldEntry.MAP_POINT_ADORN_LAYER_ID, adornData,
                        tileOffset + localOffset, false, rotation, m_DisplayCommandInterface);
                    SetAdornTileElement(tileIdx, adornData.uid, adornElement);
                }
            }
            else
            {
                if (obj != null)
                {
                    RemoveAdorn(tileIdx, adornData.uid);
                }
            }
        }
    }

    // 隐藏下一级装饰物
    public void UpdateLowPointAdornShow(int tileIdx, TilePointAdornData data,bool bShow)
    {
        if (data != null && data.lowLevelIds != null)
        {
            for (int i = 0; i < data.lowLevelIds.Count; i++)
            {
                int uid = data.lowLevelIds[i];
                UpdateAdornShow( tileIdx,  uid,  bShow);
            }
        }
    }

    public bool GetHightPointAdornShow(int tileIdx, TilePointAdornData data)
    {
        bool bShow = false;
        if (data != null && data.hightLevelIds != null)
        {
            for (int i = 0; i < data.hightLevelIds.Count; i++)
            {
                int uid = data.hightLevelIds[i];
                CommandTileElement adron = GetAdornElement(tileIdx, uid);
                if (adron != null)
                {
                    bShow = true;
                    break;
                }
            }
        }
        return bShow;
    }

    public bool GetPointState(int tileIdx, int cfgIdx)
    {
        bool state = false;
        if (mapPointState.ContainsKey(tileIdx))
        {
            Dictionary<int, bool> adorns = mapPointState[tileIdx];
            if (adorns.ContainsKey(cfgIdx))
            {
                state = adorns[cfgIdx];
            }
        }
        return state;
    }

    public void SetPointState(int tileIdx, int cfgIdx, bool state)
    {
        if (!mapPointState.ContainsKey(tileIdx))
        {
            mapPointState[tileIdx] = new Dictionary<int, bool>();
        }
        mapPointState[tileIdx][cfgIdx] = state;
    }

    public bool GetPointState2(int tileIdx, int pointIdx)
    {
        bool state = false;
        if (mapPointState2.ContainsKey(tileIdx))
        {
            Dictionary<int, bool> adorns = mapPointState2[tileIdx];
            if (adorns.ContainsKey(pointIdx))
            {
                state = adorns[pointIdx];
            }
        }
        return state;
    }

    public void SetPointState2(int tileIdx, int pointIdx, bool state)
    {
        if (!mapPointState2.ContainsKey(tileIdx))
        {
            mapPointState2[tileIdx] = new Dictionary<int, bool>();
        }
        mapPointState2[tileIdx][pointIdx] = state;
    }
    
    public bool GetPointDisAdorn(int tileIdx, int cfgIdx)
    {
        bool state = false;
        if (mapPointDisAdorn.ContainsKey(tileIdx))
        {
            Dictionary<int, bool> adorns = mapPointDisAdorn[tileIdx];
            if (adorns.ContainsKey(cfgIdx))
            {
                state = adorns[cfgIdx];
            }
        }
        return state;
    }

    public void SetPointDisAdorn(int tileIdx, int cfgIdx, bool disAdorn)
    {
        if (!mapPointDisAdorn.ContainsKey(tileIdx))
        {
            mapPointDisAdorn[tileIdx] = new Dictionary<int, bool>();
        }
        mapPointDisAdorn[tileIdx][cfgIdx] = disAdorn;
    }

    public int GetPointPosIdx(int tileIdx, int cfgIdx)
    {
        int posIdx = -1;
        if (mapPointPosIdx.ContainsKey(tileIdx))
        {
            Dictionary<int, int> posIdxs = mapPointPosIdx[tileIdx];
            if (posIdxs.ContainsKey(cfgIdx))
            {
                posIdx = posIdxs[cfgIdx];
            }
        }
        return posIdx;
    }

    public void SetPointPosIdx(int tileIdx, int cfgIdx, int posIdx)
    {
        if (!mapPointPosIdx.ContainsKey(tileIdx))
        {
            mapPointPosIdx[tileIdx] = new Dictionary<int, int>();
        }
        mapPointPosIdx[tileIdx][cfgIdx] = posIdx;
    }

    public void ClearPointStateByTileIdx(int tileIdx)
    {
        if (mapPointState.ContainsKey(tileIdx))
        {
            mapPointState[tileIdx].Clear();
        }
        if (mapPointState2.ContainsKey(tileIdx))
        {
            mapPointState2[tileIdx].Clear();
        }
    }

    public int GetLocalIdx(int idx_x, int idx_y)
    {
        int localIdx = -1;
        localIdx = idx_x + idx_y * _chunckSize;
        return localIdx;
    }

    public void SetAdornTileElement(int tileIdx, int uid, CommandTileElement element)
    {
        if (!mapAdornElements.ContainsKey(tileIdx))
        {
            mapAdornElements[tileIdx] = new Dictionary<int, CommandTileElement>();
        }
        mapAdornElements[tileIdx][uid] = element;
    }

    public CommandTileElement GetAdornElement(int tileIdx, int uid)
    {
        CommandTileElement element = null;
        if (mapAdornElements.ContainsKey(tileIdx))
        {
            Dictionary<int, CommandTileElement> elements = mapAdornElements[tileIdx];
            elements.TryGetValue(uid, out element);
        }
        return element;
    }

    public void SetTile(int tileIdx, int cfgIdx, CommandTileElement obj)
    {
        if (!mapTiles.ContainsKey(tileIdx))
        {
            mapTiles[tileIdx] = new Dictionary<int, CommandTileElement>();
        }
        mapTiles[tileIdx][cfgIdx] = obj;
    }

    public CommandTileElement GetTile(int tileIdx, int cfgIdx)
    {
        CommandTileElement obj = null;
        if (mapTiles.ContainsKey(tileIdx))
        {
            Dictionary<int, CommandTileElement> adorns = mapTiles[tileIdx];
            adorns.TryGetValue(cfgIdx, out obj);
        }
        return obj;
    }

    public void RemoveTile(int tileIdx, int cfgIdx)
    {
        CommandTileElement tile = GetTile(tileIdx, cfgIdx);
        if (tile != null)
        {
            ClassPoolManager.RecoverCommandTileEle(tile);
            mapTiles[tileIdx].Remove(cfgIdx);
        }
    }

    public void UpdateAdornShow(int tileIdx, int uid, bool bShow)
    {
        CommandTileElement adorn = GetAdornElement(tileIdx, uid);
        if (adorn != null && adorn.m_isHide != !bShow)
        {
            adorn.RefreshElementData(adorn.m_MapLayer);
        }
    }

    // 重置装饰物 -用于切换服务器用
    public void ResetAdorn()
    {
        mapPointState.Clear();
        mapPointState2.Clear();
        foreach (var adorns in mapAdornElements.Values)
        {
            if (adorns != null)
            {
                foreach (var adorn in adorns.Values)
                {
                    if (adorn != null)
                    {
                        ClassPoolManager.RecoverCommandTileEle(adorn);
                    }
                }
            }
        }
        mapAdornElements.Clear();
        foreach (var tiles in mapTiles.Values)
        {
            if (tiles != null)
            {
                foreach (var tile in tiles.Values)
                {
                    if (tile != null)
                    {
                        ClassPoolManager.RecoverCommandTileEle(tile);
                    }
                }
            }
        }
        mapTiles.Clear();
        string AddIdxs = "";
        foreach (var tileIdx in mapShowTileIdxs.Keys)
        {
            if (mapShowTileIdxs[tileIdx])
            {
                AddIdxs = AddIdxs + tileIdx + ",";
            }
        }
        // 调用lua发送请求
        luaSendFunc?.Call(AddIdxs, "");
    }

    // ============================================================ 数据 ============================================================ 

    // 视野更新当前显示的tileIdx下标
    public void AddShowTileIdx(int startX,int startY,int endX,int endY)
    {
        if (endX * endY < 0) return;// 负数的地块不需要请求
        startX = Mathf.Max(startX, 0);
        startY = Mathf.Max(startY, 0);
        string AddIdxs = "";
        for (int j = startY; j <= endY; j++)
        {
            var startIndex = j * _allianceTileLineNum;
            for (int i = startX; i <= endX; i++)
            {
                int tileIdx = startIndex + i;
                // 计算新增
                if (!mapShowTileIdxs.ContainsKey(tileIdx) || !mapShowTileIdxs[tileIdx])
                {
                    Debug.Log(string.Format("[出生点装饰物] AddShowTileIdx ===================== tileIdx {0} ： pos（{1},{2} _allianceTileLineNum {3}）", tileIdx, i, j, _allianceTileLineNum));   
                    AddIdxs = AddIdxs + tileIdx + ",";
                   
                }
                mapShowTileIdxs[tileIdx] = true;
            }
        }
        // 调用lua发送请求
        luaSendFunc?.Call(AddIdxs, "");
    }

    public void RemoveShowTileIdx(int startX, int startY, int endX, int endY)
    {
        if (endX * endY < 0) return;// 负数的地块不需要请求
        startX = Mathf.Max(startX, 0);
        startY = Mathf.Max(startY, 0);
        string DeleteIdxs = "";
        for (int j = startY; j <= endY; j++)
        {
            var startIndex = j * _allianceTileLineNum;
            for (int i = startX; i <= endX; i++)
            {
                int tileIdx = startIndex + i;
                DeleteIdxs = DeleteIdxs + tileIdx + ",";
                if(mapShowTileIdxs.ContainsKey(tileIdx)) mapShowTileIdxs.Remove(tileIdx);
                // 删除本地对应装饰物
                RemoveTileAdorn(tileIdx);
            }
        }
        // 调用lua发送请求
        luaSendFunc?.Call("", DeleteIdxs);
    }

    // 处理tileIdx 对应点数据
    public void OnTilePointData(int tileIdx,string data)
    {
        //StopwatchHelper.Instance.StartWatch("[OnTilePointData]", true);
        // 处理数据
        ClearPointStateByTileIdx(tileIdx);
        int chunckId = GetChunckId(tileIdx, out int rotation);
        Vector3 tileOffset = WorldMapConfigData.GetTileOffset(tileIdx);

        string[] strDtas = data.Split(",");
        for (int i = 0; i < strDtas.Length; i++)
        {
            string strCfgIdx = strDtas[i];
            if(!strCfgIdx.IsNotEmpty()) continue;
            int posIdx = -1;
            int.TryParse(strCfgIdx, out posIdx);
            if (posIdx < 0) continue;

            Vector3 worldPos = GetPosByPosIdx(tileIdx, posIdx);
            float idx_x = worldPos.x % WorldEntry.m_iTileSize;
            float idx_y = worldPos.z % WorldEntry.m_iTileSize;
            Vector3 cfg_v3 = WorldMapConfigData.GetPosByAngle2(idx_x - _chunckHalfSize, 0, idx_y - _chunckHalfSize, rotation);
            int cfgIdx = GetLocalIdx((int)(cfg_v3.x + _chunckHalfSize), (int)(cfg_v3.z + _chunckHalfSize)); // 配置中的localIdx

//            Debug.Log(string.Format("[出生点装饰物] ===================== tileIdx {4}|{0} ： pos（{1},{2} -> {3}）", posIdx, worldPos.x, worldPos.z, cfgIdx, tileIdx));
 
            SetPointState(tileIdx, cfgIdx, true);
            SetPointState2(tileIdx, posIdx, true);
            SetPointPosIdx(tileIdx, cfgIdx, posIdx);
        }
        // 判断当前显示
        if(mapShowTileIdxs.ContainsKey(tileIdx))
        {
            // 先清除可能存在的装饰物 + 地表
            // 更新显示该tileIdx的装饰物和地表
            UpdateAdornLevel2(chunckId, tileIdx, tileOffset, rotation, E_AdornType.E_Level_n);
            UpdateAdornLevel2(chunckId, tileIdx, tileOffset, rotation, E_AdornType.E_Level_2);
            UpdateAdornLevel2(chunckId, tileIdx, tileOffset, rotation, E_AdornType.E_Level_1);
            UpdateAdornRoad2(chunckId, tileIdx, tileOffset, rotation);
            UpdatePointTile2(chunckId, tileIdx, rotation);
        }
        //StopwatchHelper.Instance.EndWatch("[OnTilePointData]", true);
    }

    // 处理单个posIdx数据
    public void OnUpdateTilePointData(int tileIdx, int posIdx, bool bShow)
    {
        if (mapShowTileIdxs.ContainsKey(tileIdx))
        {
            Vector3 worldPos = GetPosByPosIdx(tileIdx, posIdx);
            UpdatePointState(tileIdx, posIdx, bShow, worldPos.x, worldPos.z, 0);
        }
    }

    // 更新装饰物
    public void UpdateAdornLevel2(int chunckId, int tileIdx, Vector3 tileOffset, int rotation, E_AdornType type)
    {
        // 1、获取装饰物
        List<TilePointAdornData> adornDatas = GetChunckAdornDatas(chunckId, (int)type);
        if (adornDatas == null) return;
        for (int x = 0; x < adornDatas.Count; x++)
        {
            TilePointAdornData adornData = adornDatas[x];
            // 2、判断该多级装饰物显示条件满足
            bool bShow = true;
            for (int i = 0; i < adornData.pointIdxs.Count; i++)
            {
                int pointCfgIdx = adornData.pointIdxs[i];
                bool bPointShow = GetPointState(tileIdx, pointCfgIdx);
                bool disAdorn = GetPointDisAdorn(tileIdx, pointCfgIdx);
                if (!bPointShow || disAdorn)
                {
                    bShow = false;
                    break;
                }
            }

            if (bShow)
            {
                // 4、新增多级装饰物
                CommandTileElement obj = GetAdornElement(tileIdx, adornData.uid);
                if (obj == null)
                {
                    Vector3 localOffset = WorldMapConfigData.GetPosByAngle(adornData.position.x, 0, adornData.position.z, rotation);
                    bool bHide = GetHightPointAdornShow(tileIdx, adornData);
                    CommandTileElement adornElement = CommandTileElement.Create(WorldEntry.MAP_POINT_ADORN_LAYER_ID, adornData,
                        tileOffset + localOffset, bHide, rotation, m_DisplayCommandInterface);
                    SetAdornTileElement(tileIdx, adornData.uid, adornElement);
                    // 5、隐藏所有下级装饰物
                    UpdateLowPointAdornShow(tileIdx, adornData, false);
                }
            }
        }
    }

    // 更新衔接车道
    public void UpdateAdornRoad2(int chunckId, int tileIdx, Vector3 tileOffset, int rotation)
    {
        List<TilePointAdornData> adornDatas = GetChunckAdornDatas(chunckId, (int)E_AdornType.E_Road);
        if (adornDatas == null) return;
        for (int x = 0; x < adornDatas.Count; x++)
        {
            TilePointAdornData adornData = adornDatas[x];
            bool bPointShow = GetPointState(tileIdx, adornData.pointIdxs[0]);
            if (!bPointShow) continue;
            // 检查adornData所在街区点是否显示
            Vector3 localOffset = WorldMapConfigData.GetPosByAngle(adornData.position.x, 0, adornData.position.z, rotation);
            Vector3 worldPos = localOffset + tileOffset;
            int allianceIdx = DynamicLayerMgr.worldEntry._alliancePointSystem.GetMapIdx(worldPos.x, worldPos.z);
            bool bAlliancePointShow = DynamicLayerMgr.worldEntry._alliancePointSystem.GetAlliancePointShow(allianceIdx);
            if (!bAlliancePointShow) return;
            CommandTileElement obj = GetAdornElement(tileIdx, adornData.uid);
            if (obj == null)
            {
                CommandTileElement adornElement = CommandTileElement.Create(WorldEntry.MAP_POINT_ADORN_LAYER_ID, adornData,
                                 worldPos, false, rotation, m_DisplayCommandInterface);
                SetAdornTileElement(tileIdx, adornData.uid, adornElement);
            }
        }
    }

    bool[] tempConnet = new bool[4] { false, false, false, false };
    // 更新地表
    public void UpdatePointTile2(int chunckId, int tileIdx, int rotation,bool isUpdate = false)
    {
        if (mapPointState.ContainsKey(tileIdx))
        {
            Dictionary<int, bool> points = mapPointState[tileIdx];
            foreach (int cfgIdx in points.Keys)
            {
                bool bUpdate = isUpdate == false;
                if (isUpdate) bUpdate = tempNeedUpdateTileCfgIdx.ContainsKey(cfgIdx);
                if (!bUpdate) continue;
                if (points[cfgIdx])
                {
                    List<TilePointAdornData> adornDatas = GetAdornDatas(chunckId, cfgIdx, (int)E_AdornType.E_Level_2);
                    if (adornDatas == null) continue;

                    // 计算对应的连接
                    int connetNum = 0;
                    for (int i = 0; i < tempConnet.Length; i++)
                    {
                        tempConnet[i] = false;
                    }

                    for (int i = 0; i < adornDatas.Count; i++)
                    {
                        TilePointAdornData adornData = adornDatas[i];
                        if (GetAdornElement(tileIdx, adornData.uid) != null)
                        {
                            connetNum++;
                            int adornType = adornData.type;
                            int pointIdx2 = adornData.pointIdxs[1];

                            if (pointIdx2 == cfgIdx) // 相反方向
                            {
                                adornType = adornData.type + 2;
                                if (adornType > 8) adornType -= 4;
                            }

                            int connectType = adornType - 5;
                            tempConnet[connectType] = true;
                        }
                    }
                    GetConnectRes(connetNum, out int resId, out int angle);
                    // 判断重复
                    CommandTileElement tileObj = GetTile(tileIdx, cfgIdx);
                    int rotationInt = angle + rotation;
                    if (tileObj != null && (tileObj.GetResId() != resId || tileObj.GetRotationInt() != rotationInt))
                    {
                        ClassPoolManager.RecoverCommandTileEle(tileObj);
                        tileObj = null;
                    }

                    // 新增
                    if (tileObj == null)
                    {
                        int posIdx = GetPointPosIdx(tileIdx, cfgIdx);
                        if (posIdx > 0)
                        {
                            Vector3 worldPos = GetPosByPosIdx(tileIdx, posIdx); 
                            //tileObj = WorldPoolManager.GetWorldObject(1, WorldEntry.MAP_POINT_ADORN_LAYER_ID, resId) as AdornObject;
                            //tileObj.SetPosition(worldPos);
                            //tileObj.SetScale(Vector3.one);
                            //tileObj.SetRotation(Vector3.up * rotationInt * 90);
                            //tileObj.SetRotationInt(rotationInt);
                            TilePointAdornData adornData = new TilePointAdornData();
                            adornData.resId = resId;
                            CommandTileElement adornElement = CommandTileElement.Create(WorldEntry.MAP_POINT_ADORN_LAYER_ID, adornData,
                                    worldPos, false, rotationInt, m_DisplayCommandInterface);

                            SetTile(tileIdx, cfgIdx, adornElement);
                            //tileObj.GetRefTrans.gameObject.name = tileIdx + "_" + cfgIdx;
                        }
                    }
                    else
                    {
                        int posIdx = GetPointPosIdx(tileIdx, cfgIdx);
                        if (posIdx > 0)
                        {
                            Vector3 worldPos = GetPosByPosIdx(tileIdx, posIdx);
                            tileObj.SetPosition(worldPos);
                        }
                    }
                }
                else
                {
                    RemoveTile(tileIdx, cfgIdx);
                }
            }
        }
    }

    // 根据连接情况获得连接地板资源id
    public void GetConnectRes(int connetNum, out int resId, out int angle)
    {
        int firstConnetIdx = -1;
        int firstBreakIdx = -1;
        int secondBreakIdx = -1;

        for (int i = 0; i < tempConnet.Length; i++)
        {
            bool connect = tempConnet[i];
            if (firstConnetIdx < 0 && connect)
            {
                firstConnetIdx = i;
            }
            if (firstBreakIdx < 0 && !connect)
            {
                firstBreakIdx = i;
            }
            else if (secondBreakIdx < 0 && !connect)
            {
                secondBreakIdx = i;
            }
        }
        angle = 0;
        if (connetNum == 4)
        {
            resId = m_tile_resId_5;
        }
        else if (connetNum == 3)
        {
            resId = m_tile_resId_4;
            // 默认状态是1
            angle = ((firstBreakIdx - 1) + 4) % 4;
        }
        else if (connetNum == 2)
        {
            if (Mathf.Abs(firstBreakIdx - secondBreakIdx) == 2)
            {
                resId = m_tile_resId_6;
                // 计算旋转
                // 默认状态是1
                if (firstBreakIdx == 1 || firstBreakIdx == 3) angle = 0;
                if (firstBreakIdx == 0 || firstBreakIdx == 2) angle = 1;
            }
            else if (Mathf.Abs(firstBreakIdx - secondBreakIdx) == 3)
            {
                resId = m_tile_resId_3;
                angle = secondBreakIdx;
            }
            else
            {
                resId = m_tile_resId_3;
                // 计算旋转
                angle = firstBreakIdx;
            }
        }
        else if (connetNum == 1)
        {
            resId = m_tile_resId_2;
            // 默认状态是2
            angle = ((firstConnetIdx - 2) + 4) % 4;
        }
        else
        {
            resId = m_tile_resId_1;
        }
    }

    public void RemoveTileAdorn(int tileIdx)
    {
        if (mapPointState.ContainsKey(tileIdx))
        {
            mapPointState.Remove(tileIdx);
        }
        if (mapPointState2.ContainsKey(tileIdx))
        {
            mapPointState2.Remove(tileIdx);
        }
        if (mapAdornElements.TryGetValue(tileIdx, out Dictionary<int, CommandTileElement> adorns))
        {
            foreach (CommandTileElement adorn in adorns.Values)
            {
                ClassPoolManager.RecoverCommandTileEle(adorn);
            }
            mapAdornElements.Remove(tileIdx);
        }

        if (mapTiles.TryGetValue(tileIdx, out Dictionary<int, CommandTileElement> tiles))
        {
            foreach (CommandTileElement tile in tiles.Values)
            {
                ClassPoolManager.RecoverCommandTileEle(tile);
            }
            mapTiles.Remove(tileIdx);
        }
    }
}